package com.xintai.approval.service.impl;

import java.util.*;

import com.xintai.approval.Utils.CommitUtils;
import com.xintai.approval.Utils.FlowIdSortUtils;
import com.xintai.approval.Utils.priorityLevelSortUtils;
import com.xintai.approval.domain.*;
import com.xintai.approval.mapper.*;
import com.xintai.common.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import com.xintai.approval.service.IFlowApplyService;


import javax.annotation.Resource;

/**
 * 申请Service业务层处理
 *
 * @author xintai
 * @date 2021-02-01
 */
@Service
public class FlowApplyServiceImpl implements IFlowApplyService
{
    @Resource
    private FlowApplyMapper flowApplyMapper;
    @Resource
    private ConditionMapper conditionMapper;
    @Resource
    private NodeConfigMapper nodeConfigMapper;
    @Resource
    private FlowBasicinfoMapper flowBasicinfoMapper;
    @Resource
    private FlowWorkflowMapper flowWorkflowMapper;
    @Resource
    private FlowCaigouApplyMapper flowCaigouApplyMapper;


    /**
     * 查询申请
     *
     * @param id 申请ID
     * @return 申请
     */
    @Override
    public FlowApply selectFlowApplyById(Long id)
    {
        FlowApply flowApply = flowApplyMapper.selectFlowApplyById(id);
        FlowCaigouApply flowCaiGouApply = flowCaigouApplyMapper.selectFlowCaigouApplyById(flowApply.getDetailId());
        String caigouType = flowCaiGouApply.getCaigouType();
        String[] strings = CommitUtils.strToArr(caigouType);
        flowCaiGouApply.setArrCaigou(strings);
        flowApply.setFlowCaiGouApply(flowCaiGouApply);
        return flowApply;
    }

    /**
     * 查询申请列表
     *
     * @param flowApply 申请
     * @return 申请
     */
    @Override
    public List<FlowApply> selectFlowApplyList(FlowApply flowApply)
    {
        return flowApplyMapper.selectFlowApplyList(flowApply);
    }

    /**
     * 新增申请
     *
     * @param apply 申请
     * @return 结果
     */
    @Override
    public int insertFlowApply(FlowApply apply)
    {
        apply.setApplyName(SecurityUtils.getLoginUser().getUser().getNickName());
        apply.setApplyTime(new Date());
        return flowApplyMapper.insertFlowApply(apply);
    }

    /**
     * 修改申请
     *
     * @param flowApply 申请
     * @return 结果
     */
    @Override
    public int updateFlowApply(FlowApply flowApply)
    {
        FlowCaigouApply flowCaiGouApply = flowApply.getFlowCaiGouApply();
        String s = CommitUtils.arrToStr(flowCaiGouApply.getArrCaigou());
        flowCaiGouApply.setCaigouType(s);
        flowCaigouApplyMapper.updateFlowCaigouApply(flowCaiGouApply);
        return flowApplyMapper.updateFlowApply(flowApply);
    }

    /**
     * 批量删除申请
     *
     * @param ids 需要删除的申请ID
     * @return 结果
     */
    @Override
    public int deleteFlowApplyByIds(Long[] ids)
    {
        flowWorkflowMapper.delFlowWorkflow(ids);
        return flowApplyMapper.deleteFlowApplyByIds(ids);
    }

    /**
     * 删除申请信息
     *
     * @param id 申请ID
     * @return 结果
     */
    @Override
    public int deleteFlowApplyById(Long id)
    {

        return flowApplyMapper.deleteFlowApplyById(id);
    }

    /**
     * 发起申请
     * @param flowApply
     * @return
     */
    @Override
    public int apply(FlowApply flowApply) {

        /**
         * 1.通过流程id获取发起节点
         * 2.通过节点解析定义的流程
         *  2.1.保存流程
         * */
        Long flowId = flowApply.getFlowId();
        FlowBasicinfo flowBasicinfo = flowBasicinfoMapper.selectFlowBasicinfoById(flowId);
        NodeConfig start = nodeConfigMapper.getStart(flowBasicinfo.getFlowId());
        HashMap<String, Object> map = new HashMap<>();
       // map.put("days",2);
        String[] str = CommitUtils.strToArr(flowApply.getFlowCaiGouApply().getCaigouType());
        map.put("boxType",str);
        //该申请的流程
        ArrayList<NodeConfig> flow = SelectNodeConfig(start, map, new ArrayList<>());
        FlowApply Apply = insertFlow(flow, flowApply);
        //状态
        Apply.setStatus("3");
        return flowApplyMapper.updateFlowApply(Apply);
    }

    /**
     * 进程
     * @return
     */
    @Override
    public List<FlowWorkflow> course( Long id) {
       List<FlowWorkflow> flowWorkflow = flowWorkflowMapper.selectFlowWorkflowApplyId(id);
        for (FlowWorkflow workflow : flowWorkflow) {
            String userName = "";
            List<NodeUser> nodeUsers = flowWorkflowMapper.selectNodeUser(workflow.getId());
            for (NodeUser nodeUser : nodeUsers) {
                userName = userName + nodeUser.getName() + ",";
            }
            if (!userName.equals(""))
            userName = userName.substring(0, userName.length() - 1);
            workflow.setApproverUid(userName);
        }
        return flowWorkflow;
    }

    /**
     * 解析流程
     *
     * @param nodeConfig
     * @return
     */
    public ArrayList<NodeConfig> SelectNodeConfig(NodeConfig nodeConfig, Map map, ArrayList<NodeConfig> list) {
        if (nodeConfig.getType()==1||nodeConfig.getType()==2){
            list.add(nodeConfig);
        }
        //下一级
        if (nodeConfig.getChildNodeId() != null) {
            NodeConfig child = nodeConfigMapper.selectNodeConfig(nodeConfig.getChildNodeId());
            SelectNodeConfig(child,map,list);
            nodeConfig.setChildNode(child);
        }
        //条件节点
        if (nodeConfig.getConditionNodesId() != null) {
            /**
             * 1.获取路由下的分支
             *   1.1.根据每个分支的优先级进行排序
             *   1.2.遍历路由节点的多个分支
             * 2.遍历每个分支的条件
             *   2.1.获取条件进行判断是否符合该条件，如果符合该条件递归该路由下的分支并结束循环,否就跳出该循环
             *
             * */
            //获取条件
            List<NodeConfig> conditionNodeNodeConfig = nodeConfigMapper.SelectConditionNodes(nodeConfig.getFlowId());
            //条件排序
            Collections.sort(conditionNodeNodeConfig,new priorityLevelSortUtils());
            //储存
            List<NodeConfig> conditionList = new ArrayList<>();
            //遍历多个节点
            loop:for (int i = 0; i < conditionNodeNodeConfig.size(); i++) {
                Long flowId = conditionNodeNodeConfig.get(i).getFlowId();
                List<Condition> conditions = conditionMapper.SelectConditionList(flowId);
                if (conditions!=null && !conditions.isEmpty()){
                    //遍历条件
                    for (Condition condition : conditions) {
                        //Zdy1=3天
                        if (condition.getColumnType().equals("Double")&&condition.getColumnId()==1){
                            if (Integer.valueOf(condition.getZdy1())<Integer.parseInt(map.get("days").toString())){
                                conditionList.add(conditionNodeNodeConfig.get(i));
                                nodeConfig.setConditionNodes(conditionList);
                                SelectNodeConfig(conditionNodeNodeConfig.get(i),map,list);
                                break loop;
                            }
                        }
                        //选择的标题
                        if (condition.getColumnType().equals("String")&&condition.getColumnId()==3){
                            String[] split = CommitUtils.strToArr(condition.getZdy1());
                            String[] boxType = (String[]) map.get("boxType");
                            //1: 镀锌生产线 2: 镀锌基建 3: 办公用品
                            if (CommitUtils.arrBaoH(split,boxType)){
                                conditionList.add(conditionNodeNodeConfig.get(i));
                                nodeConfig.setConditionNodes(conditionList);
                                SelectNodeConfig(conditionNodeNodeConfig.get(i),map,list);
                                break loop;
                            }
                        }
                        break ;
                    }
                }else {
                    conditionList.add(conditionNodeNodeConfig.get(i));
                    nodeConfig.setConditionNodes(conditionList);
                    SelectNodeConfig(conditionNodeNodeConfig.get(i),map,list);
                }
            }
        }
        //条件
        if (nodeConfig.getConditionListId() != null) {
            List<Condition> conditions = conditionMapper.SelectConditionList(nodeConfig.getFlowId());
            nodeConfig.setConditionList(conditions);
        } else {
            List<Condition> condition = new ArrayList<>();
            nodeConfig.setConditionList(condition);
        }

        //用户判断
        if (nodeConfig.getNodeUserListId() != null) {
            List<NodeUser> nodeUsers = nodeConfigMapper.SelectNodeUserList(nodeConfig.getFlowId());
            for (NodeUser nodeUser : nodeUsers) {
                nodeUser.setType(1);
            }
            nodeConfig.setNodeUserList(nodeUsers);
        } else {
            List<NodeUser> nodeUser = new ArrayList<>();
            nodeConfig.setNodeUserList(nodeUser);
        }

        return list;
    }


    /**
     * 添加流程表
     * @param nodeConfig
     * @param
     */
    public FlowApply insertFlow(List<NodeConfig> nodeConfig,FlowApply flowApply ){
        Collections.sort(nodeConfig,new FlowIdSortUtils());
        //遍历添加流程表
        Long upId = 0L;
        for (int i = 0; i < nodeConfig.size(); i++) {
            FlowWorkflow flowWorkflow = new FlowWorkflow();
            String userIds = "";
            //遍历当前点的审核人
            List<NodeUser> nodeUserList = nodeConfig.get(i).getNodeUserList();
            for (NodeUser user : nodeUserList) {
                userIds = userIds + user.getTargetId() + ",";
            }
            if (!userIds.equals("")){
                String user = userIds.substring(0, userIds.length() - 1);
                flowWorkflow.setApproverUid(user);
            }
            //开始审核
            if (i==0){
                flowWorkflow.setStatus("1");
                flowWorkflow.setUpNodeId(0L);
            }else {
                flowWorkflow.setUpNodeId(upId);
            }
            flowWorkflow.setNodeType(String.valueOf(nodeConfig.get(i).getType()));
            flowWorkflow.setOrderNum((i+1)*100L);
            flowWorkflow.setApplyId(flowApply.getId());
            flowWorkflowMapper.insertFlowWorkflow(flowWorkflow);
            if (i==0){
                upId = flowWorkflow.getId();
                flowApply.setNodeId(upId);
            }
            //第二条开始就修改第一条
            if (i>0){
                    Long id = flowWorkflow.getId();
                    flowWorkflowMapper.updateFlowWorkflowDown(upId,id);
                    upId = id;
                    }
            if (nodeConfig.size()-i==1){
                flowWorkflowMapper.updateFlowWorkflowDown(upId,0L);
            }
        }
       return flowApply;
    }
}
